"""
Kivy版古诗词跟读器
=================

基于Kivy框架开发的古诗词跟读应用，具有现代化界面和丰富的功能特性
"""

import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.spinner import Spinner
from kivy.uix.slider import Slider
from kivy.uix.popup import Popup
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelItem
from kivy.properties import NumericProperty, StringProperty, ListProperty, BooleanProperty
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
from kivy.core.text import LabelBase
from kivy.config import Config
import json
import os
from pypinyin import lazy_pinyin, Style

# 设置窗口大小
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '800')
Config.write()

# 注册中文字体
def register_chinese_font():
    """注册中文字体以支持中文显示"""
    # Windows系统常用中文字体路径
    font_paths = [
        ("C:/Windows/Fonts/msyh.ttc", "微软雅黑"),      # 微软雅黑
        ("C:/Windows/Fonts/msyh.ttf", "微软雅黑"),      # 微软雅黑
        ("C:/Windows/Fonts/simhei.ttf", "黑体"),       # 黑体
        ("C:/Windows/Fonts/simsun.ttc", "宋体"),       # 宋体
        ("C:/Windows/Fonts/simkai.ttf", "楷体"),       # 楷体
        ("C:/Windows/Fonts/simfang.ttf", "仿宋")       # 仿宋
    ]
    
    # 尝试注册字体
    for path, name in font_paths:
        if os.path.exists(path):
            try:
                LabelBase.register(name=name, fn_regular=path)
                print(f"成功注册字体: {name}")
                return name
            except Exception as e:
                print(f"注册字体失败 {name}: {e}")
                continue
    return None

class PoetryData:
    """诗词数据管理类"""
    
    def __init__(self, data_file="poetry_data.json"):
        self.data_file = data_file
        self.poetry_list = []
        self.load_data()
    
    def load_data(self):
        """加载诗词数据"""
        try:
            # 获取当前脚本所在目录
            current_dir = os.path.dirname(os.path.abspath(__file__))
            data_path = os.path.join(current_dir, self.data_file)
            
            with open(data_path, 'r', encoding='utf-8') as f:
                self.poetry_list = json.load(f)
            print(f"成功加载 {len(self.poetry_list)} 首诗词")
        except Exception as e:
            print(f"加载诗词数据失败: {e}")
            # 如果加载失败，使用默认数据
            self.poetry_list = [
                {
                    "title": "静夜思",
                    "author": "李白",
                    "dynasty": "唐",
                    "content": [
                        "床前明月光",
                        "疑是地上霜",
                        "举头望明月",
                        "低头思故乡"
                    ]
                }
            ]

class PoetryDisplay(Screen):
    """诗词显示界面"""
    # 当前行和字符索引
    current_line = NumericProperty(0)
    current_char = NumericProperty(0)
    
    def __init__(self, poetry_data, chinese_font=None, **kwargs):
        super(PoetryDisplay, self).__init__(**kwargs)
        self.name = 'main'
        self.poetry_data = poetry_data
        self.chinese_font = chinese_font
        
        # 当前诗词索引
        self.current_poetry_index = 0
        self.current_poetry = self.poetry_data.poetry_list[self.current_poetry_index]
        
        # 跟读状态
        self.is_reading = False
        self.event = None
        
        # 设置
        self.settings = {
            "reading_speed": 1.0,
            "show_pinyin": True,
            "theme": "经典",
            "animation_type": "character"
        }
        
        # 创建UI
        self.create_ui()
        
    def create_ui(self):
        """创建用户界面"""
        # 主布局
        main_layout = BoxLayout(orientation='vertical', padding=10, spacing=10)
        
        # 顶部工具栏
        toolbar = BoxLayout(size_hint=(1, 0.1), spacing=10)
        
        # 诗词选择下拉框
        poetry_names = [f"{poem['title']} - {poem['author']}" for poem in self.poetry_data.poetry_list]
        self.spinner = Spinner(
            text=poetry_names[0],
            values=poetry_names,
            size_hint=(0.4, 1)
        )
        if self.chinese_font:
            self.spinner.font_name = self.chinese_font
        self.spinner.bind(text=self.on_poetry_selected)
        toolbar.add_widget(self.spinner)
        
        # 主题选择
        themes = ["经典", "水墨", "雅致", "夜间"]
        self.theme_spinner = Spinner(
            text="经典",
            values=themes,
            size_hint=(0.2, 1)
        )
        if self.chinese_font:
            self.theme_spinner.font_name = self.chinese_font
        self.theme_spinner.bind(text=self.on_theme_selected)
        toolbar.add_widget(Label(text='主题:', size_hint=(0.1, 1)))
        toolbar.add_widget(self.theme_spinner)
        
        # 全屏按钮
        fullscreen_btn = Button(text='全屏', size_hint=(0.1, 1))
        if self.chinese_font:
            fullscreen_btn.font_name = self.chinese_font
        fullscreen_btn.bind(on_press=self.toggle_fullscreen)
        toolbar.add_widget(fullscreen_btn)
        
        main_layout.add_widget(toolbar)
        
        # 诗词显示区域
        self.create_poetry_display_area(main_layout)
        
        # 控制面板
        self.create_control_panel(main_layout)
        
        # 状态栏
        self.create_status_bar(main_layout)
        
        self.add_widget(main_layout)
        
    def create_poetry_display_area(self, parent_layout):
        """创建诗词显示区域"""
        # 标题区域
        title_layout = BoxLayout(size_hint=(1, 0.15), spacing=10)
        
        # 标题标签
        self.title_label = Label(
            text=f"{self.current_poetry['title']}",
            font_size='32sp',
            bold=True
        )
        if self.chinese_font:
            self.title_label.font_name = self.chinese_font
        title_layout.add_widget(self.title_label)
        
        # 作者标签
        self.author_label = Label(
            text=f"{self.current_poetry['dynasty']} · {self.current_poetry['author']}",
            font_size='24sp'
        )
        if self.chinese_font:
            self.author_label.font_name = self.chinese_font
        title_layout.add_widget(self.author_label)
        
        parent_layout.add_widget(title_layout)
        
        # 诗词显示区域（带滚动）
        self.scroll_view = ScrollView(size_hint=(1, 0.6))
        self.poetry_layout = GridLayout(cols=1, spacing=25, size_hint_y=None)
        self.poetry_layout.bind(minimum_height=self.poetry_layout.setter('height'))
        
        self.line_labels = []
        self.pinyin_labels = []
        
        # 创建诗词行标签
        self.update_poetry_display()
        
        self.scroll_view.add_widget(self.poetry_layout)
        parent_layout.add_widget(self.scroll_view)
        
    def update_poetry_display(self):
        """更新诗词显示"""
        # 清除现有内容
        self.poetry_layout.clear_widgets()
        self.line_labels.clear()
        self.pinyin_labels.clear()
        
        # 更新标题和作者
        self.title_label.text = self.current_poetry['title']
        self.author_label.text = f"{self.current_poetry['dynasty']} · {self.current_poetry['author']}"
        
        # 创建诗词行标签
        for i, line in enumerate(self.current_poetry['content']):
            # 拼音标签
            if self.settings["show_pinyin"]:
                pinyin_text = " ".join(lazy_pinyin(line, style=Style.TONE))
                pinyin_label = Label(
                    text=pinyin_text,
                    font_size='18sp',
                    color=(0.5, 0.5, 0.5, 1),
                    size_hint_y=None,
                    height=35
                )
                if self.chinese_font:
                    pinyin_label.font_name = self.chinese_font
                self.poetry_layout.add_widget(pinyin_label)
                self.pinyin_labels.append(pinyin_label)
            
            # 诗句标签
            line_label = Label(
                text=line,
                font_size='26sp',
                size_hint_y=None,
                height=60
            )
            if self.chinese_font:
                line_label.font_name = self.chinese_font
            self.poetry_layout.add_widget(line_label)
            self.line_labels.append(line_label)
            
    def create_control_panel(self, parent_layout):
        """创建控制面板"""
        control_layout = BoxLayout(size_hint=(1, 0.2), spacing=15)
        
        # 左侧按钮组
        left_buttons = BoxLayout(orientation='horizontal', spacing=10, size_hint_x=0.6)
        
        # 开始/停止按钮
        self.start_stop_btn = Button(text='开始跟读', font_size='20sp')
        if self.chinese_font:
            self.start_stop_btn.font_name = self.chinese_font
        self.start_stop_btn.bind(on_press=self.toggle_reading)
        left_buttons.add_widget(self.start_stop_btn)
        
        # 暂停按钮
        self.pause_btn = Button(text='暂停', font_size='20sp', disabled=True)
        if self.chinese_font:
            self.pause_btn.font_name = self.chinese_font
        self.pause_btn.bind(on_press=self.pause_reading)
        left_buttons.add_widget(self.pause_btn)
        
        # 设置按钮
        settings_btn = Button(text='设置', font_size='20sp')
        if self.chinese_font:
            settings_btn.font_name = self.chinese_font
        settings_btn.bind(on_press=self.open_settings)
        left_buttons.add_widget(settings_btn)
        
        control_layout.add_widget(left_buttons)
        
        # 右侧控制组
        right_controls = BoxLayout(orientation='vertical', spacing=5, size_hint_x=0.4)
        
        # 速度控制
        speed_layout = BoxLayout(spacing=10)
        speed_layout.add_widget(Label(text='速度:', font_size='18sp', size_hint_x=0.3))
        if self.chinese_font:
            speed_layout.children[0].font_name = self.chinese_font
            
        self.speed_slider = Slider(min=0.3, max=3.0, value=1.0, size_hint_x=0.5)
        self.speed_slider.bind(value=self.on_speed_change)
        speed_layout.add_widget(self.speed_slider)
        
        self.speed_label = Label(text='1.0x', font_size='18sp', size_hint_x=0.2)
        if self.chinese_font:
            self.speed_label.font_name = self.chinese_font
        speed_layout.add_widget(self.speed_label)
        
        right_controls.add_widget(speed_layout)
        
        # 导航按钮
        nav_layout = BoxLayout(spacing=10)
        self.prev_btn = Button(text='上一首', font_size='18sp')
        if self.chinese_font:
            self.prev_btn.font_name = self.chinese_font
        self.prev_btn.bind(on_press=self.previous_poetry)
        nav_layout.add_widget(self.prev_btn)
        
        self.next_btn = Button(text='下一首', font_size='18sp')
        if self.chinese_font:
            self.next_btn.font_name = self.chinese_font
        self.next_btn.bind(on_press=self.next_poetry)
        nav_layout.add_widget(self.next_btn)
        
        right_controls.add_widget(nav_layout)
        control_layout.add_widget(right_controls)
        
        parent_layout.add_widget(control_layout)
        
    def create_status_bar(self, parent_layout):
        """创建状态栏"""
        status_layout = BoxLayout(size_hint=(1, 0.05))
        
        self.status_label = Label(
            text='就绪',
            font_size='16sp',
            halign='left'
        )
        if self.chinese_font:
            self.status_label.font_name = self.chinese_font
        status_layout.add_widget(self.status_label)
        
        parent_layout.add_widget(status_layout)
        
    def on_poetry_selected(self, spinner, text):
        """处理诗词选择"""
        # 根据选择的文本找到对应的诗词索引
        for i, poem in enumerate(self.poetry_data.poetry_list):
            if f"{poem['title']} - {poem['author']}" == text:
                self.current_poetry_index = i
                break
                
        self.current_poetry = self.poetry_data.poetry_list[self.current_poetry_index]
        self.update_poetry_display()
        self.reset_highlight()
        
    def on_theme_selected(self, spinner, text):
        """处理主题选择"""
        self.settings["theme"] = text
        self.apply_theme()
        
    def apply_theme(self):
        """应用主题"""
        theme_colors = {
            "经典": {"bg": (1, 1, 0.9, 1), "text": (0, 0, 0, 1), "highlight": (1, 0, 0, 1)},
            "水墨": {"bg": (0.9, 0.9, 0.9, 1), "text": (0, 0, 0, 1), "highlight": (0.8, 0, 0, 1)},
            "雅致": {"bg": (0.9, 0.95, 1, 1), "text": (0, 0, 0, 1), "highlight": (1, 0.5, 0.5, 1)},
            "夜间": {"bg": (0.2, 0.2, 0.2, 1), "text": (1, 1, 1, 1), "highlight": (1, 0.8, 0, 1)}
        }
        
        colors = theme_colors.get(self.settings["theme"], theme_colors["经典"])
        
        # 更新背景色
        with self.canvas.before:
            Color(*colors["bg"][:3])
            Rectangle(pos=self.pos, size=self.size)
            
        # 更新文本颜色
        self.title_label.color = colors["text"]
        self.author_label.color = colors["text"]
        
        # 更新诗句颜色
        for label in self.line_labels:
            label.color = colors["text"]
            
        # 更新拼音颜色
        for label in self.pinyin_labels:
            label.color = (0.5, 0.5, 0.5, 1)
            
    def toggle_fullscreen(self, instance):
        """切换全屏模式"""
        from kivy.core.window import Window
        Window.fullscreen = not Window.fullscreen
        
    def toggle_reading(self, instance):
        """切换跟读状态"""
        if not self.is_reading:
            self.start_reading()
        else:
            self.stop_reading()
            
    def start_reading(self):
        """开始跟读"""
        self.is_reading = True
        self.start_stop_btn.text = '停止跟读'
        self.pause_btn.disabled = False
        
        # 重置高亮
        self.reset_highlight()
        
        # 开始跟读动画
        self.current_line = 0
        self.current_char = 0
        self.reading_step()
        
        self.status_label.text = '正在跟读...'
        
    def stop_reading(self):
        """停止跟读"""
        self.is_reading = False
        self.start_stop_btn.text = '开始跟读'
        self.pause_btn.disabled = True
        self.pause_btn.text = '暂停'
        
        # 取消定时器
        if self.event:
            self.event.cancel()
            
        # 重置高亮
        self.reset_highlight()
        
        self.status_label.text = '就绪'
        
    def pause_reading(self, instance):
        """暂停跟读"""
        if self.is_reading:
            self.is_reading = False
            self.pause_btn.text = '继续'
            self.status_label.text = '已暂停'
            if self.event:
                self.event.cancel()
        else:
            self.is_reading = True
            self.pause_btn.text = '暂停'
            self.status_label.text = '正在跟读...'
            self.reading_step()
            
    def reading_step(self):
        """跟读步骤"""
        if not self.is_reading:
            return
            
        # 获取当前行
        if self.current_line < len(self.current_poetry['content']):
            line = self.current_poetry['content'][self.current_line]
            chars = list(line)
            
            # 如果还有字符未读完
            if self.current_char < len(chars):
                # 高亮当前字符
                self.highlight_character(self.current_line, self.current_char)
                self.current_char += 1
                
                # 根据速度设置下次调用时间
                speed = self.speed_slider.value
                delay = 0.5 / speed
                self.event = Clock.schedule_once(lambda dt: self.reading_step(), delay)
            else:
                # 行结束，移动到下一行
                self.current_line += 1
                self.current_char = 0
                
                # 如果还有下一行
                if self.current_line < len(self.current_poetry['content']):
                    # 等待一段时间后继续
                    speed = self.speed_slider.value
                    delay = 1.0 / speed
                    self.event = Clock.schedule_once(lambda dt: self.reading_step(), delay)
                else:
                    # 全部读完，停止
                    self.stop_reading()
                    self.status_label.text = '跟读完成！'
                    # 2秒后恢复状态
                    Clock.schedule_once(lambda dt: setattr(self.status_label, 'text', '就绪'), 2)
        else:
            # 全部读完，停止
            self.stop_reading()
            self.status_label.text = '跟读完成！'
            # 2秒后恢复状态
            Clock.schedule_once(lambda dt: setattr(self.status_label, 'text', '就绪'), 2)
            
    def highlight_character(self, line_idx, char_idx):
        """高亮字符"""
        # 重置所有行的颜色
        for i, label in enumerate(self.line_labels):
            if i < len(self.current_poetry['content']):
                if i < line_idx:
                    # 已经读过的行，使用完成颜色
                    label.color = (0, 0.8, 0, 1)  # 绿色
                elif i == line_idx:
                    # 当前行，部分高亮
                    line = self.current_poetry['content'][i]
                    chars = list(line)
                    
                    # 创建带高亮的文本
                    highlighted_text = ""
                    for j, char in enumerate(chars):
                        if j <= char_idx:
                            highlighted_text += f"[color=ff0000]{char}[/color]"
                        else:
                            highlighted_text += char
                            
                    label.text = highlighted_text
                    label.markup = True
                else:
                    # 未读的行，使用默认颜色
                    label.color = (1, 1, 1, 1)  # 白色
                    label.text = self.current_poetry['content'][i]
                    label.markup = False
                    
    def reset_highlight(self):
        """重置高亮"""
        for i, label in enumerate(self.line_labels):
            if i < len(self.current_poetry['content']):
                label.color = (1, 1, 1, 1)  # 白色
                label.text = self.current_poetry['content'][i]
                label.markup = False
                
    def on_speed_change(self, instance, value):
        """处理速度变化"""
        self.speed_label.text = f"{value:.1f}x"
        self.settings["reading_speed"] = value
        
    def previous_poetry(self, instance):
        """上一首诗词"""
        if self.current_poetry_index > 0:
            self.current_poetry_index -= 1
            self.spinner.text = f"{self.poetry_data.poetry_list[self.current_poetry_index]['title']} - {self.poetry_data.poetry_list[self.current_poetry_index]['author']}"
            self.current_poetry = self.poetry_data.poetry_list[self.current_poetry_index]
            self.update_poetry_display()
            self.reset_highlight()
            
    def next_poetry(self, instance):
        """下一首诗词"""
        if self.current_poetry_index < len(self.poetry_data.poetry_list) - 1:
            self.current_poetry_index += 1
            self.spinner.text = f"{self.poetry_data.poetry_list[self.current_poetry_index]['title']} - {self.poetry_data.poetry_list[self.current_poetry_index]['author']}"
            self.current_poetry = self.poetry_data.poetry_list[self.current_poetry_index]
            self.update_poetry_display()
            self.reset_highlight()
            
    def open_settings(self, instance):
        """打开设置窗口"""
        # 创建设置弹窗
        content = BoxLayout(orientation='vertical', padding=10, spacing=10)
        
        # 标题
        title = Label(text='设置', font_size='24sp', size_hint=(1, 0.1))
        if self.chinese_font:
            title.font_name = self.chinese_font
        content.add_widget(title)
        
        # 设置选项
        settings_layout = GridLayout(cols=2, spacing=10, size_hint=(1, 0.8))
        
        # 显示拼音选项
        settings_layout.add_widget(Label(text='显示拼音:', font_size='18sp'))
        if self.chinese_font:
            settings_layout.children[-1].font_name = self.chinese_font
            
        self.pinyin_switch = Button(
            text='开' if self.settings["show_pinyin"] else '关',
            font_size='18sp'
        )
        if self.chinese_font:
            self.pinyin_switch.font_name = self.chinese_font
        self.pinyin_switch.bind(on_press=self.toggle_pinyin)
        settings_layout.add_widget(self.pinyin_switch)
        
        # 动画类型选项
        settings_layout.add_widget(Label(text='动画类型:', font_size='18sp'))
        if self.chinese_font:
            settings_layout.children[-1].font_name = self.chinese_font
            
        animation_types = ["逐字符", "逐行"]
        self.animation_spinner = Spinner(
            text="逐字符" if self.settings["animation_type"] == "character" else "逐行",
            values=animation_types,
            font_size='18sp'
        )
        if self.chinese_font:
            self.animation_spinner.font_name = self.chinese_font
        settings_layout.add_widget(self.animation_spinner)
        
        content.add_widget(settings_layout)
        
        # 按钮
        button_layout = BoxLayout(size_hint=(1, 0.1), spacing=10)
        
        apply_btn = Button(text='应用', font_size='18sp')
        if self.chinese_font:
            apply_btn.font_name = self.chinese_font
        apply_btn.bind(on_press=self.apply_settings)
        button_layout.add_widget(apply_btn)
        
        close_btn = Button(text='关闭', font_size='18sp')
        if self.chinese_font:
            close_btn.font_name = self.chinese_font
        close_btn.bind(on_press=lambda x: popup.dismiss())
        button_layout.add_widget(close_btn)
        
        content.add_widget(button_layout)
        
        popup = Popup(
            title='设置',
            content=content,
            size_hint=(0.6, 0.6)
        )
        if self.chinese_font:
            popup.title_font = self.chinese_font
        popup.open()
        
    def toggle_pinyin(self, instance):
        """切换拼音显示"""
        self.settings["show_pinyin"] = not self.settings["show_pinyin"]
        self.pinyin_switch.text = '开' if self.settings["show_pinyin"] else '关'
        
    def apply_settings(self, instance):
        """应用设置"""
        # 更新动画类型
        if self.animation_spinner.text == "逐字符":
            self.settings["animation_type"] = "character"
        else:
            self.settings["animation_type"] = "line"
            
        # 更新显示
        self.update_poetry_display()
        self.reset_highlight()

class KivyPoetryReaderApp(App):
    def build(self):
        self.title = 'Kivy版古诗词跟读器'
        
        # 注册中文字体
        self.chinese_font = register_chinese_font()
        
        # 加载诗词数据
        self.poetry_data = PoetryData()
        
        # 创建屏幕管理器
        sm = ScreenManager()
        
        # 添加主屏幕
        main_screen = PoetryDisplay(self.poetry_data, self.chinese_font)
        sm.add_widget(main_screen)
        
        return sm

if __name__ == '__main__':
    KivyPoetryReaderApp().run()